﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 购物车接口实现
    /// </summary>
    public class ShopCartService : BaseService, IShopCartService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;
        public ShopCartService(IDbContextFactory contentFactory,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 根据条件获取购物车列表
        /// </summary>
        public async Task<ICollection<ShopCartListDto>> GetListAsync(Expression<Func<ShopCart, bool>> funcWhere,
            WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status401Unauthorized);
            }
            //获取会员组信息
            var memberModel = await _context.Set<Members>().Where(x => x.UserId == userId).Include(x => x.Group).FirstOrDefaultAsync();
            if (memberModel == null)
            {
                throw new ResponseException("会员不存在或已删除");
            }
            //获取购物车列表
            var carList = await _context.Set<ShopCart>().Where(x => x.UserId == userId).Where(funcWhere).ToListAsync();
            //查找商家并进行分组
            if (carList == null)
            {
                throw new ResponseException("没有符合条件的购物车商品");
            }
            var merchantIds = carList.Select(x => x.MerchantId).Distinct().ToList();//商户ID去重
            //var merchantIds = list.GroupBy(p => p.MerchantId).Select(p => p.Key).ToList();
            var merchantList = await _context.Set<Merchants>()
                .Include(x=>x.Store)
                .Where(x => merchantIds.Contains(x.Id)).ToListAsync();
            //创建待赋值的实体
            ICollection<ShopCartListDto> result = new List<ShopCartListDto>();
            //遍历商户列表
            foreach(var merchant in merchantList)
            {
                var list = carList.Where(x => x.MerchantId == merchant.Id);
                var resultItem = new ShopCartListDto
                {
                    MerchantId = merchant.Id,
                    MerchantTitle = merchant.Title,
                    MerchantAvatar = merchant.Avatar,
                    StoreTitle = merchant.Store?.Title,
                    IsSelf = merchant.IsSelf
                };
                //遍历购物车商品
                foreach (var item in list)
                {
                    //创建购物车实体用于存放,使用AutoMapper映射
                    var mapModel = _mapper.Map<ShopCartDto>(item);
                    //获取商品信息
                    var productModel = await _context.Set<ShopGoodsProduct>().Where(x => x.Id == item.ProductId)
                        .Include(x => x.ShopGoods)
                        .Include(x => x.GroupPrices).FirstOrDefaultAsync();
                    if (productModel != null)
                    {
                        //计算出会员组折扣价格
                        int discount = memberModel.Group?.Discount ?? 100;
                        decimal groupPrice = productModel.SellPrice * ((decimal)discount / 100);
                        //计算出商品会员组价格
                        var priceModel = productModel.GroupPrices.FirstOrDefault(x => x.GroupId == memberModel.GroupId);
                        if (priceModel != null)
                        {
                            groupPrice = priceModel.Price;
                        }
                        //给购物车实体赋值
                        mapModel.GoodsId = productModel.GoodsId;
                        mapModel.MarketPrice = productModel.MarketPrice;
                        mapModel.SellPrice = productModel.SellPrice;
                        mapModel.GroupPrice = groupPrice;
                        mapModel.Weight = productModel.Weight;
                        mapModel.StockQuantity = productModel.StockQuantity;
                        mapModel.Status = productModel.ShopGoods?.Status == 0 ? (byte)0 : (byte)1;
                        resultItem.Goods.Add(mapModel);
                    }
                }
                //如果有商品才添加购物列表
                if(resultItem.Goods.Count > 0)
                {
                    result.Add(resultItem);
                }
            }
            return result;
        }

        /// <summary>
        /// 添加到购物车
        /// </summary>
        public async Task<bool> AddAsync(ShopCartEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status422UnprocessableEntity);
            }
            //查询商品货品信息
            var productModel = await _context.Set<ShopGoodsProduct>().Where(x => x.Id == modelDto.ProductId && x.ShopGoods!.Status == 0)
                    .Include(x => x.ShopGoods)
                    .Include(x => x.GroupPrices).FirstOrDefaultAsync();
            if (productModel == null)
            {
                throw new ResponseException($"商品{productModel?.Id}不存在或已下架");
            }
            
            //检查是否已存在，不存在新增否则修改数量
            var cartModel = await _context.Set<ShopCart>().FirstOrDefaultAsync(
                x => x.UserId == userId && x.ProductId == modelDto.ProductId);
            if (cartModel != null)
            {
                cartModel.Quantity += modelDto.Quantity;
                //检查最小购买数量
                if (cartModel.Quantity < productModel.MinQuantity)
                {
                    throw new ResponseException($"该商品至少购买{productModel.MinQuantity}件");
                }
                _context.Set<ShopCart>().Update(cartModel);
                return await this.SaveAsync();
            }
            else
            {
                //检查最小购买数量
                if (modelDto.Quantity < productModel.MinQuantity)
                {
                    throw new ResponseException($"该商品至少购买{productModel.MinQuantity}件");
                }
                //查询商品信息保存到数据
                var model = new ShopCart
                {
                    UserId = userId,
                    MerchantId = productModel.ShopGoods?.MerchantId ?? 0,
                    Title = productModel.ShopGoods?.Title,
                    SkuText = productModel.SkuText,
                    ImgUrl = productModel.ImgUrl ?? productModel.ShopGoods?.ImgUrl,
                    ProductId = productModel.Id,
                    Quantity = modelDto.Quantity
                };
                await _context.Set<ShopCart>().AddAsync(model);
                return await this.SaveAsync();
            }
        }

        /// <summary>
        /// 更新购物车数量
        /// </summary>
        public async Task<bool> UpdateAsync(long id, int quantity, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status422UnprocessableEntity);
            }
            //检查是否已存在，不存在新增否则修改数量
            var model = await _context.Set<ShopCart>().FirstOrDefaultAsync(x => x.UserId == userId && x.Id == id);
            if (model == null)
            {
                throw new ResponseException($"数据{id}不存在或已删除");
            }
            //查询商品货品信息
            var productModel = await _context.Set<ShopGoodsProduct>().Where(x => x.Id == model.ProductId && x.ShopGoods!.Status == 0)
                    .Include(x => x.ShopGoods)
                    .Include(x => x.GroupPrices).FirstOrDefaultAsync();
            if (productModel == null)
            {
                throw new ResponseException($"商品{productModel?.Id}不存在或已下架");
            }
            //检查最小购买数量
            if (quantity < productModel.MinQuantity)
            {
                throw new ResponseException($"该商品至少购买{productModel.MinQuantity}件");
            }
            model.Quantity = quantity;
            _context.Set<ShopCart>().Update(model);
            return await this.SaveAsync();
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<ShopCart, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status422UnprocessableEntity);
            }
            //查询购物车列表
            var list = await _context.Set<ShopCart>().Where(x => x.UserId == userId)
                .Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            _context.Set<ShopCart>().RemoveRange(list);
            return await this.SaveAsync();
        }

        /// <summary>
        /// 获取商品统计和列表
        /// </summary>
        public async Task<ShopCartTotalDto> GetBuyListAsync(List<ShopCartEditDto> buyLlist, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //检查是否有商品
            if (buyLlist == null)
            {
                throw new ResponseException("请选择购买的商品");
            }
            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status401Unauthorized);
            }
            //获取会员组信息
            var memberModel = await _context.Set<Members>().Where(x => x.UserId == userId).Include(x => x.Group).FirstOrDefaultAsync();
            if (memberModel == null)
            {
                throw new ResponseException("会员不存在或已删除");
            }
            //查询会员组折扣
            int discount = memberModel.Group?.Discount ?? 100;
            //获取商品列表
            var productList = await _context.Set<ShopGoodsProduct>().Where(x => buyLlist.Select(p => p.ProductId).Contains(x.Id))
                    .Include(x => x.ShopGoods)
                    .Include(x => x.GroupPrices).ToListAsync();
            if (productList == null)
            {
                throw new ResponseException("未查询到商品信息");
            }
            //查找商家并进行分组
            var shopGoodsList = productList.Select(x => x.ShopGoods).ToList();
            var merchantIds = shopGoodsList.Select(x => x?.MerchantId).Distinct().ToList();//商户ID去重
            var merchantList = await _context.Set<Merchants>()
                .Include(x => x.Store)
                .Where(x => merchantIds.Contains(x.Id)).ToListAsync();
            //创建待赋值的实体
            ShopCartTotalDto result = new();
            //遍历商户列表
            foreach(var merchant in merchantList)
            {
                var list = productList.Where(x => x.ShopGoods?.MerchantId == merchant.Id);
                var resultItem = new ShopCartTotalListDto
                {
                    MerchantId = merchant.Id,
                    MerchantTitle = merchant.Title,
                    MerchantAvatar = merchant.Avatar,
                    StoreTitle = merchant.Store?.Title
                };
                //遍历符合商户的商品
                foreach (var item in list)
                {
                    //计算出会员组折扣价格
                    decimal groupPrice = decimal.Round(item.SellPrice * ((decimal)discount / 100), 2);
                    //计算出商品会员组价格
                    var priceModel = item.GroupPrices.FirstOrDefault(x => x.GroupId == memberModel.GroupId);
                    if (priceModel != null)
                    {
                        groupPrice = priceModel.Price;
                    }
                    ShopCartDto modelDto = new()
                    {
                        Id = 0,
                        UserId = memberModel.UserId,
                        MerchantId = item.ShopGoods?.MerchantId ?? 0,
                        Status = item.ShopGoods?.Status == 0 ? (byte)0 : (byte)1,
                        AddTime = DateTime.Now,
                        GoodsId = item.GoodsId,
                        Title = item.ShopGoods?.Title,
                        SkuText = item.SkuText,
                        ImgUrl = item.ImgUrl ?? item.ShopGoods?.ImgUrl,
                        MarketPrice = item.MarketPrice,
                        SellPrice = item.SellPrice,
                        GroupPrice = groupPrice,
                        Weight = item.Weight,
                        StockQuantity = item.StockQuantity,
                        ProductId = item.Id,
                        Quantity = buyLlist.FirstOrDefault(x => x.ProductId == item.Id)?.Quantity ?? 0
                    };
                    //非免运费商品标记
                    if (item.ShopGoods?.IsDeliveryFee == 0)
                    {
                        resultItem.FreeFreight = 0;
                    }
                    //加入列表
                    resultItem.Goods.Add(modelDto);
                }
                //统计商户购物车属性
                resultItem.TotalQuantity = resultItem.Goods.Select(x => x.Quantity).Sum();
                resultItem.TotalWeight = resultItem.Goods.Select(x => x.Weight * x.Quantity).Sum();
                resultItem.PayableAmount = resultItem.Goods.Select(x => x.SellPrice * x.Quantity).Sum();
                resultItem.RealAmount = resultItem.Goods.Select(x => x.GroupPrice * x.Quantity).Sum();
                resultItem.OrderAmount = resultItem.RealAmount;

                //获取商户配送列表(前10条)
                var deliveryList = await _context.Set<ShopDelivery>()
                    .Include(x => x.DeliveryAreas)
                    .Where(x => x.IsDelete == 0 && x.Status == 0 && x.MerchantId == merchant.Id)
                    .OrderByBatch("SortId,-Id")
                    .Take(10)
                    .ToListAsync();
                //转换成DTO
                resultItem.ShopDeliverys = _mapper.Map<List<ShopDeliveryCartDto>>(deliveryList);

                //获取会员可用优惠券
                var couponList = await _context.Set<ShopCouponHistory>()
                    .Include(x => x.ShopCoupon).ThenInclude(x => x!.GoodsRelations)
                    .Where(x => x.UserId == userId
                        && x.ShopCoupon.IsDelete == 0
                        && x.Status == 0
                        && x.IsUse == 0
                        && x.ShopCoupon != null
                        && x.ShopCoupon.MerchantId == merchant.Id
                        && DateTime.Compare(x.ShopCoupon.StartTime, DateTime.Now) <= 0
                        && DateTime.Compare(x.ShopCoupon.EndTime, DateTime.Now) >= 0)
                    .Take(10)
                    .ToListAsync();
                //声明存储列表，将符合条件的优惠券放进去
                List<ShopCouponHistory> resultCouponList = new();
                //遍历购物券，查找与商品匹配的购物券加入到可用购物券列表
                foreach (var coupon in couponList)
                {
                    //0.店铺券
                    if (coupon.ShopCoupon?.UseType == 0)
                    {
                        //如果不限金额或商品金额大于等于购物券设定的值则有效
                        if (coupon.ShopCoupon.MinAmount == 0 || resultItem.Goods.Select(x => x.SellPrice * x.Quantity).Sum() >= coupon.ShopCoupon.MinAmount)
                        {
                            resultCouponList.Add(coupon);
                        }
                    }
                    //1.商品券
                    else if (coupon.ShopCoupon?.UseType == 1)
                    {
                        //取出优惠券可用商品ID
                        var couponGoodsIds = coupon.ShopCoupon.GoodsRelations.Select(x => x.GoodsId);
                        //查找符合条件的商品
                        var goodsIds = resultItem.Goods.Where(x => couponGoodsIds.Contains(x.GoodsId)).Select(x => x.GoodsId);
                        if (goodsIds != null
                            && resultItem.Goods.Where(x => goodsIds.Contains(x.GoodsId)).Select(x => x.SellPrice * x.Quantity).Sum() >= coupon.ShopCoupon.MinAmount)
                        {
                            resultCouponList.Add(coupon);
                        }
                    }
                }
                //转换成DTO
                resultItem.ShopCoupons = _mapper.Map<List<ShopCouponHistoryCartDto>>(resultCouponList);

                //获取促销活动列表
                var promotionModel = await _context.Set<ShopPromotion>().FirstOrDefaultAsync(x => x.IsDelete == 0
                    && x.MerchantId == merchant.Id
                    && x.Status == 0
                    && DateTime.Compare(x.StartTime, DateTime.Now) <= 0
                    && DateTime.Compare(x.EndTime, DateTime.Now) >= 0);
                if (promotionModel != null)
                {
                    //奖励阶梯满减
                    if (promotionModel.AwardType == 1 && resultItem.RealAmount > promotionModel.Condition)
                    {
                        //计算阶梯满减倍数
                        var discountNum = (int)(resultItem.RealAmount / promotionModel.Condition);
                        //订单金额=原实付-阶梯满减金额
                        resultItem.PromotionAmount = discountNum * promotionModel.AwardValue;
                        resultItem.OrderAmount = resultItem.RealAmount - resultItem.PromotionAmount;

                    }
                    //奖励折扣
                    else if (promotionModel.AwardType == 2 && resultItem.RealAmount > promotionModel.Condition)
                    {
                        if (promotionModel.AwardValue < 1 || promotionModel.AwardValue > 100)
                        {
                            throw new ResponseException($"活动{promotionModel.Id}折扣设置有误");
                        }
                        //订单金额=原实付*折扣
                        resultItem.OrderAmount = resultItem.RealAmount * ((decimal)promotionModel.AwardValue / 100);
                        resultItem.PromotionAmount = Math.Round(resultItem.RealAmount - resultItem.OrderAmount);
                    }
                    //促销活动信息
                    resultItem.Promotion = _mapper.Map<ShopPromotionDto>(promotionModel);
                }
                //加入列表项
                result.List.Add(resultItem);
            }
            //商品总统计
            result.TotalQuantity = result.List.Select(x => x.TotalQuantity).Sum();
            result.TotalRealAmount = result.List.Select(x => x.RealAmount).Sum();
            result.TotalPromotionAmount = result.List.Select(x => x.PromotionAmount).Sum();
            result.TotalOrderAmount = result.List.Select(x => x.OrderAmount).Sum();
            return result;
        }

        /// <summary>
        /// 获取购物车商品总数量
        /// </summary>
        public async Task<int> QueryCountAsync(Expression<Func<ShopCart, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            return await _context.Set<ShopCart>().Where(funcWhere).CountAsync();
        }

    }
}
